// xlocmon internal header (from <locale>)
#pragma once
#ifndef _XLOCMON_
#define _XLOCMON_
#include <cerrno>
#include <xiosbase>

#pragma pack(push,8)
#pragma warning(push,3)
_STD_BEGIN
		// STRUCT money_base
struct _CRTIMP2 money_base
	: public locale::facet
	{	// ultimate base class for moneypunct
	enum
		{	// constants for different format codes
		symbol = '$', sign = '+', space = ' ', value = 'v', none = 'x'};
	typedef int part;

	struct pattern
		{	// four-part formats for monetary text
		char field[4];
		};

	money_base(size_t _Refs = 0)
		: locale::facet(_Refs)
		{	// default constructor
		}
	};

		// TEMPLATE CLASS _Mpunct
template<class _Elem>
	class _Mpunct
		: public money_base
	{	// common base class for moneypunct<_Elem, false/true>
public:
	typedef _Elem char_type;
	typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> >
		string_type;

	_Elem decimal_point() const
		{	// return decimal point
		return (do_decimal_point());
		}

	_Elem thousands_sep() const
		{	// return thousands separator
		return (do_thousands_sep());
		}

	string grouping() const
		{	// return grouping string
		return (do_grouping());
		}

	string_type curr_symbol() const
		{	// return currency symbol string
		return (do_curr_symbol());
		}

	string_type positive_sign() const
		{	// return plus sign
		return (do_positive_sign());
		}

	string_type negative_sign() const
		{	// return minus sign
		return (do_negative_sign());
		}

	int frac_digits() const
		{	// return number of fraction digits
		return (do_frac_digits());
		}

	pattern pos_format() const
		{	// return format for positive values
		return (do_pos_format());
		}

	pattern neg_format() const
		{	// return format for negative values
		return (do_neg_format());
		}

	explicit _Mpunct(size_t _Refs, bool _Intl)
		: money_base(_Refs), _International(_Intl)
		{	// construct from current locale
		_Init(_Locinfo());
		}

	_Mpunct(const _Locinfo& _Lobj, size_t _Refs, bool _Intl)
		: money_base(_Refs), _International(_Intl)
		{	// construct from specified locale
		_Init(_Lobj);
		}

_PROTECTED:
	virtual ~_Mpunct()
		{	// destroy the object
		_Tidy();
		}

protected:
	void _Init(const _Locinfo& _Lobj)
		{	// initialize from _Lobj
		_Cvt = _Lobj._Getcvt();
		const lconv *_Ptr = _Lobj._Getlconv();

		_Grouping = 0;
		_Currencysign = 0;
		_Plussign = 0;
		_Minussign = 0;

		_TRY_BEGIN
		_Grouping = _MAKLOCSTR(char, _Ptr->mon_grouping, _Cvt);
		_Currencysign = _MAKLOCSTR(_Elem, _International
			? _Ptr->int_curr_symbol : _Ptr->currency_symbol, _Cvt);
		_Plussign = _MAKLOCSTR(_Elem, 4 < (unsigned int)_Ptr->p_sign_posn
			? "" : _Ptr->positive_sign, _Cvt);
		_Minussign = _MAKLOCSTR(_Elem, 4 < (unsigned int)_Ptr->n_sign_posn
			? "-" : _Ptr->negative_sign, _Cvt);
		_CATCH_ALL
		_Tidy();
		_RERAISE;
		_CATCH_END

		_Decimalpoint = _MAKLOCCHR(_Elem, _Ptr->mon_decimal_point[0], _Cvt);
		_Kseparator = _MAKLOCCHR(_Elem, _Ptr->mon_thousands_sep[0], _Cvt);

		_Fracdigits = _International ? _Ptr->int_frac_digits
			: _Ptr->frac_digits;
		if (_Fracdigits < 0 || CHAR_MAX <= _Fracdigits)
			_Fracdigits = 0;

		_Makpat(_Plusformat, _Ptr->p_sep_by_space,
			_Ptr->p_cs_precedes, _Ptr->p_sign_posn);
		_Makpat(_Minusformat, _Ptr->n_sep_by_space,
			_Ptr->n_cs_precedes, _Ptr->n_sign_posn);
		}

	virtual _Elem do_decimal_point() const
		{	// return decimal point
		return (_Decimalpoint);
		}

	virtual _Elem do_thousands_sep() const
		{	// return thousands separator
		return (_Kseparator);
		}

	virtual string do_grouping() const
		{	// return grouping string
		return (string(_Grouping));
		}

	virtual string_type do_curr_symbol() const
		{	// return currency symbol string
		return (string_type(_Currencysign));
		}

	virtual string_type do_positive_sign() const
		{	// return plus sign
		return (string_type(_Plussign));
		}

	virtual string_type do_negative_sign() const
		{	// return minus sign
		return (string_type(_Minussign));
		}

	virtual int do_frac_digits() const
		{	// return number of fraction digits
		return (_Fracdigits);
		}

	virtual pattern do_pos_format() const
		{	// return format for positive values
		return (_Plusformat);
		}

	virtual pattern do_neg_format() const
		{	// return format for negative values
		return (_Minusformat);
		}

private:
	void _Makpat(pattern& _Pattern, unsigned int _Sepbyspace,
		unsigned int _Symbolprecedes, unsigned int _Signposition)
		{	// make format pattern from locale information
		const char *_Ptr = _International || (_Sepbyspace & ~1) != 0
			|| (_Symbolprecedes & ~1) != 0 || 4 < _Signposition
				? "$+vx"	// international or bad parameters
				: "+v$x" "+v$x" "v$+x" "v+$x" "v$+x"
				"+$vx" "+$vx" "$v+x" "+$vx" "$+vx"
				"+v $" "+v $" "v $+" "v+ $" "v $+"
				"+$ v" "+$ v" "$ v+" "+$ v" "$ +v"
					+ (_Signposition * 4	// pick even/odd column
					+ (_Symbolprecedes == 1 ? 20 : 0)	// pick even/odd row
					+ (_Sepbyspace == 1 ? 40 : 0));	// pick first/second half
		memcpy(_Pattern.field, _Ptr, 4);
		}

	void _Tidy()
		{	// free all storage
		_DELETE_CRT_VEC((void *)_Grouping);
		_DELETE_CRT_VEC((void *)_Currencysign);
		_DELETE_CRT_VEC((void *)_Plussign);
		_DELETE_CRT_VEC((void *)_Minussign);
		}

	const char *_Grouping;	// grouping string, "" for "C" locale
	_Elem _Decimalpoint;	// decimal point, '\0' for "C" locale
	_Elem _Kseparator;	// thousands separator, '\0' for "C" locale
	const _Elem *_Currencysign;	// currency symbol, "" for "C" locale
	const _Elem *_Plussign;	// plus sign, "" for "C" locale
	const _Elem *_Minussign;	// minus sign, "-" for "C" locale
	int _Fracdigits;	// number of fraction digits, 0 for "C" locale
	pattern _Plusformat;	// positive format, "$+vx" for "C" locale
	pattern _Minusformat;	// negative format, "$+vx" for "C" locale
	bool _International;	// true if international format

	_Locinfo::_Cvtvec _Cvt;		// conversion information
	};

		// TEMPLATE CLASS moneypunct
template<class _Elem,
	bool _Intl = false>
	class moneypunct
		: public _Mpunct<_Elem>
	{	// facet for defining monetary punctuation text
public:
	static const bool intl;	// true if international
	static locale::id id;	// unique facet id

	explicit moneypunct(size_t _Refs = 0)
		: _Mpunct<_Elem>(_Refs, _Intl)
		{	// construct from current locale
		}

	moneypunct(const _Locinfo& _Lobj, size_t _Refs = 0)
		: _Mpunct<_Elem>(_Lobj, _Refs, _Intl)
		{	// construct from specified locale
		}

	static size_t __cdecl _Getcat(const locale::facet **_Ppf = 0)
		{	// return locale category mask and construct standard facet
		if (_Ppf != 0 && *_Ppf == 0)
			*_Ppf = _NEW_CRT moneypunct<_Elem, _Intl>;
		return (_X_MONETARY);
		}
	};

		// STATIC moneypunct::intl OBJECT
template<class _Elem,
	bool _Intl>
	const bool moneypunct<_Elem, _Intl>::intl = _Intl;

		// STATIC moneypunct::id OBJECT
template<class _Elem,
	bool _Intl>
	locale::id moneypunct<_Elem, _Intl>::id;

		// TEMPLATE CLASS moneypunct_byname
template<class _Elem,
	bool _Intl = false>
	class moneypunct_byname
		: public moneypunct<_Elem, _Intl>
	{	// moneypunct for named locale
public:
	explicit moneypunct_byname(const char *_Locname, size_t _Refs = 0)
		: moneypunct<_Elem, _Intl>(_Locinfo(_Locname), _Refs)
		{	// construct for named locale
		}

_PROTECTED:
	virtual ~moneypunct_byname()
		{	// destroy the object
		}
	};

		// TEMPLATE CLASS money_get
template<class _Elem,
	class _InIt = istreambuf_iterator<_Elem, char_traits<_Elem> > >
	class money_get
		: public locale::facet
	{	// facet for converting text to encoded monetary amounts
	typedef moneypunct<_Elem, false> _Mypunct0;
	typedef moneypunct<_Elem, true> _Mypunct1;

public:
	typedef _Elem char_type;
	typedef _InIt iter_type;
	typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> >
		string_type;

	_InIt get(_InIt _First, _InIt _Last,
		bool _Intl, ios_base& _Iosbase, ios_base::iostate& _State,
			long double& _Val) const
		{	// get long double from [_First, _Last) into _Val
		return (do_get(_First, _Last, _Intl, _Iosbase, _State, _Val));
		}

	_InIt get(_InIt _First, _InIt _Last,
		bool _Intl, ios_base& _Iosbase, ios_base::iostate& _State,
			string_type& _Val) const
		{	// get string_type from [_First, _Last) into _Val
		return (do_get(_First, _Last, _Intl, _Iosbase, _State, _Val));
		}

	static locale::id id;	// unique facet id

	explicit money_get(size_t _Refs = 0)
		: locale::facet(_Refs)
		{	// construct from current locale
		_Init(_Locinfo());
		}

	money_get(const _Locinfo& _Lobj, size_t _Refs = 0)
		: locale::facet(_Refs)
		{	// construct from specified locale
		_Init(_Lobj);
		}

	static size_t __cdecl _Getcat(const locale::facet **_Ppf = 0)
		{	// return locale category mask and construct standard facet
		if (_Ppf != 0 && *_Ppf == 0)
			*_Ppf = _NEW_CRT money_get<_Elem, _InIt>;
		return (_X_MONETARY);
		}

_PROTECTED:
	virtual ~money_get()
		{	// destroy the object
		}

protected:
	void _Init(const _Locinfo& _Lobj)
		{	// initialize from _Locinfo object
		_Cvt = _Lobj._Getcvt();
		}

	virtual _InIt do_get(_InIt _First, _InIt _Last,
		bool _Intl, ios_base& _Iosbase, ios_base::iostate& _State,
			long double& _Val) const
		{	// get long double from [_First, _Last) into _Val
		string_type _Str = _Getmfld(_First, _Last, _Intl, _Iosbase);

		if (_First == _Last)
			_State |= ios_base::eofbit;
		if (_Str.size() == 0)
			_State |= ios_base::failbit;	// _Getmfld failed
		else
			{	// convert to char string, then to long double
			const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);
			string _Str2;
			_Str2.reserve(_Str.size());
			size_t _Off = 0;

			if (_Str[0] < _E0 || _E0 + 9 < _Str[0])
				_Str2 += '-', ++_Off;
			for (; _Off < _Str.size(); ++_Off)
				_Str2 += (_Str[_Off] - _E0) + '0';

			const char *_Eb = _Str2.c_str();
			char *_Ep;
			errno = 0;
			const long double _Ans = _Stold(_Eb, &_Ep, 0);	// convert

			if (_Ep == _Eb || errno != 0)
				_State |= ios_base::failbit;
			else
				_Val = _Ans;	// deliver value
			}
		return (_First);
		}

	virtual _InIt do_get(_InIt _First, _InIt _Last,
		bool _Intl, ios_base& _Iosbase, ios_base::iostate& _State,
			string_type& _Val) const
		{	// get string_type from [_First, _Last) into _Val
		string_type _Str = _Getmfld(_First, _Last, _Intl, _Iosbase);

		if (_First == _Last)
			_State |= ios_base::eofbit;
		if (_Str.size() == 0)
			_State |= ios_base::failbit;	// _Getmfld failed
		else
			_Val = _Str;	// deliver value
		return (_First);
		}

private:
	string_type _Getmfld(_InIt& _First, _InIt& _Last,
		bool _Intl, ios_base& _Iosbase) const
		{	// get monetary field from [_First, _Last) into string_type
		const _Mpunct<_Elem> *_Ppunct_fac;
		if (_Intl)
			_Ppunct_fac =
				&_USE(_Iosbase.getloc(), _Mypunct1);	// international
		else
			_Ppunct_fac =
				&_USE(_Iosbase.getloc(), _Mypunct0);	// local

		bool _Bad = false, _Neg = false;
		string_type _Sign, _Val;
		const money_base::pattern _Pattern = _Ppunct_fac->neg_format();

		for (size_t _Off = 0; !_Bad && _Off < 4; ++_Off)
			switch (_Pattern.field[_Off])
				{	// parse a format component
			case money_base::symbol:
				{	// parse currency symbol
				string_type _Symbol = _Ppunct_fac->curr_symbol();
				typename string_type::const_iterator _Source;

				if (_Iosbase.flags() & ios_base::showbase)
					;	// showbase ==> mandatory currency symbol
				else if (_Off == 3 && _Sign.size() <= 1
					&& (_First == _Last || *_First != *_Symbol.c_str()))
					_Symbol.erase();	// currency symbol optional at end

				for (_Source = _Symbol.begin();
					_First != _Last && _Source != _Symbol.end()
						&& *_First == *_Source; ++_Source, ++_First)
					;	// still matching currency symbol

				if (_Source != _Symbol.end())
					_Bad = true;	// currency symbol match failed
				break;
				}

			case money_base::sign:	// parse sign
				if (_First == _Last)
					;	// assume no sign
				else if (0 < (_Ppunct_fac->positive_sign()).size()
					&& _Ppunct_fac->positive_sign()[0] == *_First)
					{	// match positive sign
					++_First;
					_Sign = _Ppunct_fac->positive_sign();
					}
				else if (0 < (_Ppunct_fac->negative_sign()).size()
					&& _Ppunct_fac->negative_sign()[0] == *_First)
					{	// match negative sign
					++_First;
					_Sign = _Ppunct_fac->negative_sign();
					_Neg = true;
					}
				break;	// sign match can't fail

			case money_base::value:
				{	// parse value field
				int _Fracdigseen = 0;
				int _Fracdigits = _Ppunct_fac->frac_digits();
				const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);
				const string _Grouping = _Ppunct_fac->grouping();

				if (CHAR_MAX <= (unsigned char)*_Grouping.c_str())
					for (; _First != _Last
						&& _E0 <= *_First && *_First <= _E0 + 9; ++_First)
					_Val += *_First;	// no grouping, just gather digits
				else
					{	// grouping specified, gather digits and group sizes
					const _Elem _Kseparator = _Ppunct_fac->thousands_sep();
					string _Groups((size_t)1, '\0');
					size_t _Group = 0;

					for (; _First != _Last; ++_First)
						if ( _E0 <= *_First && *_First <= _E0 + 9)
							{	// got a digit, add to group size
							_Val += *_First;
							if (_Groups[_Group] != CHAR_MAX)
								++_Groups[_Group];
							}
						else if (_Groups[_Group] == '\0'
							|| _Kseparator == (_Elem)0
							|| *_First != _Kseparator)
							break;	// not a group separator, done
						else
							{	// add a new group to _Groups string
							_Groups.append((size_t)1, '\0');
							++_Group;
							}

					if (_Group == 0)
						;	// no thousands separators seen
					else if ('\0' < _Groups[_Group])
						++_Group;	// add trailing group to group count
					else
						_Bad = true;	// trailing separator, fail

					for (const char *_Pg = _Grouping.c_str();
						!_Bad && 0 < _Group; )
						if (*_Pg == CHAR_MAX)
							break;	// end of grouping constraints to check
						else if (0 < --_Group && *_Pg != _Groups[_Group]
							|| 0 == _Group && *_Pg < _Groups[_Group])
							_Bad = true;	// bad group size, fail
						else if ('\0' < _Pg[1])
							++_Pg;	// group size okay, advance to next test
					if (_Bad)
						break;	// bad grouping, give up
					}

				if (_First != _Last
					&& *_First == _Ppunct_fac->decimal_point())
					{	// seen decimal point, gather fraction digits
					while (++_First != _Last
						&& _E0 <= *_First && *_First <= _E0 + 9)
						if (_Fracdigseen < _Fracdigits)
							_Val += *_First, ++_Fracdigseen;
					}

				if (_Val.size() == 0)
					_Bad = true;	// fail if no elements parsed
				else
					for (; _Fracdigseen < _Fracdigits; ++_Fracdigseen)
						_Val += _E0;	// pad out fraction
				break;
				}

			case money_base::space:	// parse space
				if (_Off == 3)
					break;	// ignore space format at end

				const ctype<_Elem>& _Ctype_fac =
					_USE(_Iosbase.getloc(), ctype<_Elem>);
				while (_First != _Last
					&& _Ctype_fac.is(ctype_base::space, *_First))
					++_First;	// space match can't fail
				}

		if (!_Bad && 1 < _Sign.size())
			{	// match rest of sign string
			typename string_type::const_iterator _Source;

			for (_Source = _Sign.begin(); _First != _Last
				&& ++_Source != _Sign.end() && *_First == *_Source; ++_First)
				;
			if (_Source != _Sign.end())
				_Bad = true;	// rest of sign doesn't match, fail
			}

		if (_Bad)
			_Val.erase();	// bad input, return empty string
		else if (_Neg)
			_Val.insert((size_t)0, (size_t)1, _MAKLOCCHR(_Elem, '-', _Cvt));
		return (_Val);
		}

	_Locinfo::_Cvtvec _Cvt;		// conversion information
	};

		// STATIC money_get::id OBJECT
template<class _Elem,
	class _InIt>
	locale::id money_get<_Elem, _InIt>::id;

		// TEMPLATE CLASS money_put
template<class _Elem,
	class _OutIt = ostreambuf_iterator<_Elem, char_traits<_Elem> > >
	class money_put
		: public locale::facet
	{	// facet for converting encoded monetary amounts to text
	typedef moneypunct<_Elem, false> _Mypunct0;
	typedef moneypunct<_Elem, true> _Mypunct1;

public:
	typedef _Elem char_type;
	typedef _OutIt iter_type;
	typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> >
		string_type;

	_OutIt put(_OutIt _Dest,
		bool _Intl, ios_base& _Iosbase, _Elem _Fill,
			long double _Val) const
		{	// put long double to _Dest
		return (do_put(_Dest, _Intl, _Iosbase, _Fill, _Val));
		}

	_OutIt put(_OutIt _Dest,
		bool _Intl, ios_base& _Iosbase, _Elem _Fill,
			const string_type& _Val) const
		{	// put string_type to _Dest
		return (do_put(_Dest, _Intl, _Iosbase, _Fill, _Val));
		}

	static locale::id id;	// unique facet id

	explicit money_put(size_t _Refs = 0)
		: locale::facet(_Refs)
		{	// construct from current locale
		_Init(_Locinfo());
		}

	money_put(const _Locinfo& _Lobj, size_t _Refs = 0)
		: locale::facet(_Refs)
		{	// construct from specified locale
		_Init(_Lobj);
		}

	static size_t __cdecl _Getcat(const locale::facet **_Ppf = 0)
		{	// return locale category mask and construct standard facet
		if (_Ppf != 0 && *_Ppf == 0)
			*_Ppf = _NEW_CRT money_put<_Elem, _OutIt>;
		return (_X_MONETARY);
		}

_PROTECTED:
	virtual ~money_put()
		{	// destroy the object
		}

protected:
	void _Init(const _Locinfo& _Lobj)
		{	// initialize from _Locinfo object
		_Cvt = _Lobj._Getcvt();
		}

	virtual _OutIt do_put(_OutIt _Dest,
		bool _Intl, ios_base& _Iosbase, _Elem _Fill,
			long double _Val) const
		{	// put long double to _Dest
		bool _Negative = false;
		if (_Val < 0)
			_Negative = true, _Val = -_Val;

		size_t _Exp;
		for (_Exp = 0; 1e35 <= _Val && _Exp < 5000; _Exp += 10)
			_Val /= 1e10;	// drop 10 zeros before decimal point

		string_type _Val2;
		char _Buf[40];
		int _Count = ::sprintf(_Buf, "%.0Lf",
			_Val);	// convert to chars
		for (int _Off = 0; _Off < _Count; ++_Off)
			_Val2.append((typename string_type::size_type)1,
				_MAKLOCCHR(_Elem, _Buf[_Off], _Cvt));	// convert chars
		_Val2.append(_Exp,
			_MAKLOCCHR(_Elem, '0', _Cvt));	// scale by trailing zeros

		return (_Putmfld(_Dest, _Intl, _Iosbase, _Fill, _Negative, _Val2));
		}

	virtual _OutIt do_put(_OutIt _Dest,
		bool _Intl, ios_base& _Iosbase, _Elem _Fill,
			const string_type& _Val) const
		{	// put string_type to _Dest
		const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);
		const _Elem *_Ptr = _Val.c_str();
		bool _Negative = false;
		if (*_Ptr == _MAKLOCCHR(_Elem, '-', _Cvt))
			_Negative = true, ++_Ptr;

		size_t _Count;
		for (_Count = 0; _E0 <= _Ptr[_Count] && _Ptr[_Count] <= _E0 + 9;
			++_Count)
			;	// count digits
		string_type _Val2(_Ptr, _Count);
		if (_Count == 0)	// replace empty digit string with '0'
			_Val2.append((typename string_type::size_type)1, _E0);

		return (_Putmfld(_Dest, _Intl, _Iosbase, _Fill, _Negative, _Val2));
		}

private:
	_OutIt _Putmfld(_OutIt _Dest,
		bool _Intl, ios_base& _Iosbase, _Elem _Fill,
			bool _Neg, string_type _Val) const
		{	// put string_type with just digits to _Dest
		const _Mpunct<_Elem> *_Ppunct_fac;
		if (_Intl)
			_Ppunct_fac =
				&_USE(_Iosbase.getloc(), _Mypunct1);	// international
		else
			_Ppunct_fac =
				&_USE(_Iosbase.getloc(), _Mypunct0);	// local
		const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);

		size_t _Fracdigits = _Ppunct_fac->frac_digits();
		const string _Grouping = _Ppunct_fac->grouping();

		if (_Val.size() <= _Fracdigits)
			_Val.insert((size_t)0, _Fracdigits - _Val.size() + 1, _E0);
		else if (*_Grouping.c_str() != CHAR_MAX && '\0' < *_Grouping.c_str())
			{	// grouping specified, add thousands separators
			const _Elem _Kseparator = _Ppunct_fac->thousands_sep();
			const char *_Pg = _Grouping.c_str();
			size_t _Off = _Val.size() - _Fracdigits;	// start of fraction

			while (*_Pg != CHAR_MAX && '\0' < *_Pg
				&& (size_t)*_Pg < _Off)
				{	// add a thousands separator, right to left
				_Val.insert(_Off -= *_Pg, (size_t)1, _Kseparator);
				if ('\0' < _Pg[1])
					++_Pg;	// not last group, advance
				}
			}

		money_base::pattern _Pattern;
		string_type _Sign;
		if (_Neg)
			{	// negative value, choose appropriate format and sign
			_Pattern = _Ppunct_fac->neg_format();
			_Sign = _Ppunct_fac->negative_sign();
			}
		else
			{	// positive value, choose appropriate format and sign
			_Pattern = _Ppunct_fac->pos_format();
			_Sign = _Ppunct_fac->positive_sign();
			}

		string_type _Symbol;
		if (_Iosbase.flags() & ios_base::showbase)
			_Symbol = _Ppunct_fac->curr_symbol();	// showbase ==> show $

		bool _Intern = false;
		size_t _Fillcount, _Off;
		for (_Fillcount = 0, _Off = 0; _Off < 4; ++_Off)
			switch (_Pattern.field[_Off])
			{	// accumulate total length in _Fillcount
			case money_base::symbol:	// count currency symbol size
				_Fillcount += _Symbol.size();
				break;

			case money_base::sign:	// count sign size
				_Fillcount += _Sign.size();
				break;

			case money_base::value:	// count value field size
				_Fillcount += _Val.size() + (0 < _Fracdigits ? 1 : 0)
					+ (_Val.size() <= _Fracdigits
						? _Fracdigits - _Val.size() + 1 : 0);
				break;

			case money_base::space:	// count space size
				_Intern = true;
			}

		_Fillcount = _Iosbase.width() <= 0
			|| (size_t)_Iosbase.width() <= _Fillcount
				? 0 : (size_t)_Iosbase.width() - _Fillcount;

		ios_base::fmtflags _Afl =
			_Iosbase.flags() & ios_base::adjustfield;
		if (_Afl != ios_base::left
			&& (_Afl != ios_base::internal || !_Intern))
			{	// put leading fill
			_Dest = _Rep(_Dest, _Fill, _Fillcount);
			_Fillcount = 0;
			}

		for (_Off = 0; _Off < 4; ++_Off)
			switch (_Pattern.field[_Off])
				{	// put components as specified by _Pattern
			case money_base::symbol:	// put currency symbol
				_Dest = _Put(_Dest, _Symbol.begin(), _Symbol.size());
				break;

			case money_base::sign:	// put sign
				if (0 < _Sign.size())
					_Dest = _Put(_Dest, _Sign.begin(), 1);
				break;

			case money_base::value:	// put value field
				if (_Fracdigits == 0)
					_Dest = _Put(_Dest, _Val.begin(),
						_Val.size());	// no fraction part
				else if (_Val.size() <= _Fracdigits)
					{	// put leading zero, all fraction digits
					*_Dest++ = _E0;
					*_Dest++ = _Ppunct_fac->decimal_point();
					_Dest = _Rep(_Dest, _E0,
						_Fracdigits - _Val.size());	// insert zeros
					_Dest = _Put(_Dest, _Val.begin(), _Val.size());
					}
				else
					{	// put both integer and fraction parts
					_Dest = _Put(_Dest, _Val.begin(),
						_Val.size() - _Fracdigits);	// put integer part
					*_Dest++ = _Ppunct_fac->decimal_point();
					_Dest = _Put(_Dest, _Val.end() - _Fracdigits,
						_Fracdigits);	// put fraction part
					}
				break;

			case money_base::space:	// put any internal fill
				if (_Afl == ios_base::internal)
					{	// put internal fill
					_Dest = _Rep(_Dest, _Fill, _Fillcount);
					_Fillcount = 0;
					}
				}

		if (1 < _Sign.size())
			_Dest = _Put(_Dest, _Sign.begin() + 1,
				_Sign.size() - 1);	// put remainder of sign
		_Iosbase.width(0);
		return (_Rep(_Dest, _Fill, _Fillcount));	// put trailing fill
		}

	static _OutIt __cdecl _Put(_OutIt _Dest,
		typename string_type::const_iterator _Source, size_t _Count)
		{	// put [_Source, _Source + _Count) to _Dest
		for (; 0 < _Count; --_Count, ++_Dest, ++_Source)
			*_Dest = *_Source;
		return (_Dest);
		}

	static _OutIt __cdecl _Rep(_OutIt _Dest,
		_Elem _Ch, size_t _Count)
		{	// put _Count * _Ch to _Dest
		for (; 0 < _Count; --_Count, ++_Dest)
			*_Dest = _Ch;
		return (_Dest);
		}

	_Locinfo::_Cvtvec _Cvt;		// conversion information
	};

		// STATIC money_put::id OBJECT
template<class _Elem,
	class _OutIt>
	locale::id money_put<_Elem, _OutIt>::id;

 #ifdef  _DLL_CPPLIB

template class _CRTIMP2 moneypunct<char, true>;
template class _CRTIMP2 moneypunct<char, false>;
template class _CRTIMP2 money_get<char,
	istreambuf_iterator<char, char_traits<char> > >;
template class _CRTIMP2 money_put<char,
	ostreambuf_iterator<char, char_traits<char> > >;

template class _CRTIMP2 moneypunct<wchar_t, true>;
template class _CRTIMP2 moneypunct<wchar_t, false>;
template class _CRTIMP2 money_get<wchar_t,
	istreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
template class _CRTIMP2 money_put<wchar_t,
	ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >;



 #endif /* _DLL_CPPLIB */
_STD_END
#pragma warning(pop)
#pragma pack(pop)

#endif /* _XLOCMON_ */

/*
 * Copyright (c) 1992-2002 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 V3.13:0009 */
